home *** CD-ROM | disk | FTP | other *** search
/ Aminet 30 / Aminet 30 (1999)(Schatztruhe)[!][Apr 1999].iso / Aminet / gfx / misc / gnuplot-3.7src.lha / gnuplot-3.7src / gnuplot-3.7.lha / gnuplot-3.7 / plot.c < prev    next >
C/C++ Source or Header  |  1998-12-09  |  17KB  |  675 lines

  1. #ifndef lint
  2. static char *RCSid = "$Id: plot.c,v 1.87 1998/04/14 00:16:05 drd Exp $";
  3. #endif
  4.  
  5. /* GNUPLOT - plot.c */
  6.  
  7. /*[
  8.  * Copyright 1986 - 1993, 1998   Thomas Williams, Colin Kelley
  9.  *
  10.  * Permission to use, copy, and distribute this software and its
  11.  * documentation for any purpose with or without fee is hereby granted,
  12.  * provided that the above copyright notice appear in all copies and
  13.  * that both that copyright notice and this permission notice appear
  14.  * in supporting documentation.
  15.  *
  16.  * Permission to modify the software is granted, but not the right to
  17.  * distribute the complete modified source code.  Modifications are to
  18.  * be distributed as patches to the released version.  Permission to
  19.  * distribute binaries produced by compiling modified sources is granted,
  20.  * provided you
  21.  *   1. distribute the corresponding source modifications from the
  22.  *    released version in the form of a patch file along with the binaries,
  23.  *   2. add special version identification to distinguish your version
  24.  *    in addition to the base release version number,
  25.  *   3. provide your name and address as the primary contact for the
  26.  *    support of your modified version, and
  27.  *   4. retain our contact information in regard to use of the base
  28.  *    software.
  29.  * Permission to distribute the released version of the source code along
  30.  * with corresponding source modifications in the form of a patch file is
  31.  * granted with same provisions 2 through 4 for binary distributions.
  32.  *
  33.  * This software is provided "as is" without express or implied warranty
  34.  * to the extent permitted by applicable law.
  35. ]*/
  36.  
  37. #include <signal.h>
  38.  
  39. #include "plot.h"
  40. #include "fit.h"
  41. #include "setshow.h"
  42. #include "fnproto.h"
  43. #include <setjmp.h>
  44.  
  45. #if defined(MSDOS) || defined(DOS386) || defined(__EMX__)
  46. # include <io.h>
  47. #endif
  48.  
  49. /* HBB: for the control87 function, if used with DJGPP V1: */
  50. #if defined(DJGPP) && (DJGPP!=2)
  51. # include "ctrl87.h"
  52. #endif
  53.  
  54. #ifdef VMS
  55. # ifndef __GNUC__
  56. #  include <unixio.h>
  57. # endif
  58. # include <smgdef.h>
  59. extern int vms_vkid;
  60. extern smg$create_virtual_keyboard();
  61. extern int vms_ktid;
  62. extern smg$create_key_table();
  63. #endif /* VMS */
  64.  
  65. #ifdef AMIGA_SC_6_1
  66. # include <proto/dos.h>
  67. #endif
  68.  
  69. #ifdef _Windows
  70. # include <windows.h>
  71. # ifndef SIGINT
  72. #  define SIGINT 2        /* for MSC */
  73. # endif
  74. #endif /* _Windows */
  75.  
  76. extern FILE *gpoutfile;
  77.  
  78. TBOOLEAN interactive = TRUE;    /* FALSE if stdin not a terminal */
  79. TBOOLEAN noinputfiles = TRUE;    /* FALSE if there are script files */
  80.  
  81. /*  these 2 could be in misc.c, but are here with all the other globals */
  82. TBOOLEAN do_load_arg_substitution = FALSE;
  83. char *call_args[10] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
  84.  
  85. char *infile_name = NULL;    /* name of command file; NULL if terminal */
  86.  
  87. #ifdef GNU_READLINE
  88. extern char *rl_readline_name;
  89. extern int rl_complete_with_tilde_expansion;
  90. #endif
  91.  
  92. #ifdef X11
  93. extern int X11_args __PROTO((int, char **));
  94. #endif
  95.  
  96. /* patch to get home dir, see command.c */
  97. #if (defined (__TURBOC__) && (defined (MSDOS) || defined(DOS386))) || defined(DJGPP)
  98. # include <dir.h>        /* MAXPATH */
  99. char HelpFile[MAXPATH];
  100. #endif /*   - DJL */
  101.  
  102. #ifndef STDOUT
  103. # define STDOUT 1
  104. #endif
  105.  
  106. /* a longjmp buffer to get back to the command line */
  107. #ifdef _Windows
  108. static jmp_buf far command_line_env;
  109. #else
  110. static jmp_buf command_line_env;
  111. #endif
  112.  
  113. static void load_rcfile __PROTO((void));
  114. RETSIGTYPE inter __PROTO((int anint));
  115.  
  116. /* built-in function table */
  117. struct ft_entry GPFAR ft[] =
  118. {
  119.     /* internal functions: */
  120.     {"push", (FUNC_PTR) f_push},
  121.     {"pushc", (FUNC_PTR) f_pushc},
  122.     {"pushd1", (FUNC_PTR) f_pushd1},
  123.     {"pushd2", (FUNC_PTR) f_pushd2},
  124.     {"pushd", (FUNC_PTR) f_pushd},
  125.     {"call", (FUNC_PTR) f_call},
  126.     {"calln", (FUNC_PTR) f_calln},
  127.     {"lnot", (FUNC_PTR) f_lnot},
  128.     {"bnot", (FUNC_PTR) f_bnot},
  129.     {"uminus", (FUNC_PTR) f_uminus},
  130.     {"lor", (FUNC_PTR) f_lor},
  131.     {"land", (FUNC_PTR) f_land},
  132.     {"bor", (FUNC_PTR) f_bor},
  133.     {"xor", (FUNC_PTR) f_xor},
  134.     {"band", (FUNC_PTR) f_band},
  135.     {"eq", (FUNC_PTR) f_eq},
  136.     {"ne", (FUNC_PTR) f_ne},
  137.     {"gt", (FUNC_PTR) f_gt},
  138.     {"lt", (FUNC_PTR) f_lt},
  139.     {"ge", (FUNC_PTR) f_ge},
  140.     {"le", (FUNC_PTR) f_le},
  141.     {"plus", (FUNC_PTR) f_plus},
  142.     {"minus", (FUNC_PTR) f_minus},
  143.     {"mult", (FUNC_PTR) f_mult},
  144.     {"div", (FUNC_PTR) f_div},
  145.     {"mod", (FUNC_PTR) f_mod},
  146.     {"power", (FUNC_PTR) f_power},
  147.     {"factorial", (FUNC_PTR) f_factorial},
  148.     {"bool", (FUNC_PTR) f_bool},
  149.     {"dollars", (FUNC_PTR) f_dollars},    /* for using extension */
  150.     {"jump", (FUNC_PTR) f_jump},
  151.     {"jumpz", (FUNC_PTR) f_jumpz},
  152.     {"jumpnz", (FUNC_PTR) f_jumpnz},
  153.     {"jtern", (FUNC_PTR) f_jtern},
  154.  
  155. /* standard functions: */
  156.     {"real", (FUNC_PTR) f_real},
  157.     {"imag", (FUNC_PTR) f_imag},
  158.     {"arg", (FUNC_PTR) f_arg},
  159.     {"conjg", (FUNC_PTR) f_conjg},
  160.     {"sin", (FUNC_PTR) f_sin},
  161.     {"cos", (FUNC_PTR) f_cos},
  162.     {"tan", (FUNC_PTR) f_tan},
  163.     {"asin", (FUNC_PTR) f_asin},
  164.     {"acos", (FUNC_PTR) f_acos},
  165.     {"atan", (FUNC_PTR) f_atan},
  166.     {"atan2", (FUNC_PTR) f_atan2},
  167.     {"sinh", (FUNC_PTR) f_sinh},
  168.     {"cosh", (FUNC_PTR) f_cosh},
  169.     {"tanh", (FUNC_PTR) f_tanh},
  170.     {"int", (FUNC_PTR) f_int},
  171.     {"abs", (FUNC_PTR) f_abs},
  172.     {"sgn", (FUNC_PTR) f_sgn},
  173.     {"sqrt", (FUNC_PTR) f_sqrt},
  174.     {"exp", (FUNC_PTR) f_exp},
  175.     {"log10", (FUNC_PTR) f_log10},
  176.     {"log", (FUNC_PTR) f_log},
  177.     {"besj0", (FUNC_PTR) f_besj0},
  178.     {"besj1", (FUNC_PTR) f_besj1},
  179.     {"besy0", (FUNC_PTR) f_besy0},
  180.     {"besy1", (FUNC_PTR) f_besy1},
  181.     {"erf", (FUNC_PTR) f_erf},
  182.     {"erfc", (FUNC_PTR) f_erfc},
  183.     {"gamma", (FUNC_PTR) f_gamma},
  184.     {"lgamma", (FUNC_PTR) f_lgamma},
  185.     {"ibeta", (FUNC_PTR) f_ibeta},
  186.     {"igamma", (FUNC_PTR) f_igamma},
  187.     {"rand", (FUNC_PTR) f_rand},
  188.     {"floor", (FUNC_PTR) f_floor},
  189.     {"ceil", (FUNC_PTR) f_ceil},
  190.  
  191.     {"norm", (FUNC_PTR) f_normal},    /* XXX-JG */
  192.     {"inverf", (FUNC_PTR) f_inverse_erf},    /* XXX-JG */
  193.     {"invnorm", (FUNC_PTR) f_inverse_normal},    /* XXX-JG */
  194.     {"asinh", (FUNC_PTR) f_asinh},
  195.     {"acosh", (FUNC_PTR) f_acosh},
  196.     {"atanh", (FUNC_PTR) f_atanh},
  197.  
  198.     {"column", (FUNC_PTR) f_column},    /* for using */
  199.     {"valid", (FUNC_PTR) f_valid},    /* for using */
  200.     {"timecolumn", (FUNC_PTR) f_timecolumn},    /* for using */
  201.  
  202.     {"tm_sec", (FUNC_PTR) f_tmsec},    /* for timeseries */
  203.     {"tm_min", (FUNC_PTR) f_tmmin},    /* for timeseries */
  204.     {"tm_hour", (FUNC_PTR) f_tmhour},    /* for timeseries */
  205.     {"tm_mday", (FUNC_PTR) f_tmmday},    /* for timeseries */
  206.     {"tm_mon", (FUNC_PTR) f_tmmon},    /* for timeseries */
  207.     {"tm_year", (FUNC_PTR) f_tmyear},    /* for timeseries */
  208.     {"tm_wday", (FUNC_PTR) f_tmwday},    /* for timeseries */
  209.     {"tm_yday", (FUNC_PTR) f_tmyday},    /* for timeseries */
  210.  
  211.     {NULL, NULL}
  212. };
  213.  
  214. static struct udvt_entry udv_pi = { NULL, "pi", FALSE };
  215. /* first in linked list */
  216. struct udvt_entry *first_udv = &udv_pi;
  217. struct udft_entry *first_udf = NULL;
  218.  
  219. #ifdef OS2
  220. # define INCL_DOS
  221. # define INCL_REXXSAA
  222. # include <os2.h>
  223. # include <process.h>
  224. ULONG RexxInterface(PRXSTRING, PUSHORT, PRXSTRING);
  225. int ExecuteMacro(char *, int);
  226. void PM_intc_cleanup();
  227. void PM_setup();
  228. #endif /* OS2 */
  229.  
  230. #if defined(ATARI) || defined(MTOS)
  231. /* For findfile () (?) */
  232. # include <support.h>
  233. void appl_exit(void);
  234. void MTOS_open_pipe(void);
  235. extern int aesid;
  236. #endif
  237.  
  238. RETSIGTYPE inter(anint)
  239. int anint;
  240. {
  241. #ifdef OS2
  242.     (void) signal(anint, SIG_ACK);
  243. #else
  244.     (void) signal(SIGINT, (sigfunc) inter);
  245. #endif
  246.  
  247. #ifndef DOSX286
  248.     (void) signal(SIGFPE, SIG_DFL);    /* turn off FPE trapping */
  249. #endif
  250. #ifdef OS2
  251.     PM_intc_cleanup();
  252. #else
  253.     term_reset();
  254.     (void) putc('\n', stderr);
  255.     longjmp(command_line_env, TRUE);    /* return to prompt */
  256. #endif
  257. }
  258.  
  259.  
  260. /* a wrapper for longjmp so we can keep everything local */
  261. void bail_to_command_line()
  262. {
  263.     longjmp(command_line_env, TRUE);
  264. }
  265.  
  266. #if defined(_Windows) || defined(_Macintosh)
  267. int gnu_main(argc, argv)
  268. #else
  269. int main(argc, argv)
  270. #endif
  271. int argc;
  272. char **argv;
  273. {
  274. #ifdef LINUXVGA
  275.     LINUX_setup();
  276. #endif
  277. /* make sure that we really have revoked root access, this might happen if
  278.    gnuplot is compiled without vga support but is installed suid by mistake */
  279. #ifdef __linux__
  280.     setuid(getuid());
  281. #endif
  282. #if defined(MSDOS) && !defined(_Windows) && !defined(__GNUC__)
  283.     PC_setup();
  284. #endif /* MSDOS !Windows */
  285. /* HBB: Seems this isn't needed any more for DJGPP V2? */
  286. /* HBB: disable all floating point exceptions, just keep running... */
  287. #if defined(DJGPP) && (DJGPP!=2)
  288.     _control87(MCW_EM, MCW_EM);
  289. #endif
  290.  
  291. #if defined(OS2)
  292.     int rc;
  293.     if (_osmode == OS2_MODE) {
  294.     PM_setup();
  295.     rc = RexxRegisterSubcomExe("GNUPLOT", (PFN) RexxInterface, NULL);
  296.     }
  297. #endif
  298.  
  299. /* malloc large blocks, otherwise problems with fragmented mem */
  300. #ifdef OSK
  301.     _mallocmin(102400);
  302. #endif
  303.  
  304. #ifdef MALLOCDEBUG
  305.     malloc_debug(7);
  306. #endif
  307.  
  308. /* get helpfile from home directory */
  309. #ifndef DOSX286
  310. # ifndef _Windows
  311. #  if defined (__TURBOC__) && (defined (MSDOS) || defined(DOS386))
  312.     strcpy(HelpFile, argv[0]);
  313.     strcpy(strrchr(HelpFile, DIRSEP1), "\\gnuplot.gih");
  314. #  endif            /*   - DJL */
  315. # endif                /* !_Windows */
  316. #endif /* !DOSX286 */
  317. #ifdef __DJGPP__
  318.     {
  319.     char *s;
  320.     strcpy(HelpFile, argv[0]);
  321.     for (s = HelpFile; *s; s++)
  322.         if (*s == DIRSEP1)
  323.         *s = DIRSEP2;    /* '\\' to '/' */
  324.     strcpy(strrchr(HelpFile, DIRSEP2), "/gnuplot.gih");
  325.     }        /* Add also some "paranoid" tests for '\\':  AP */
  326. #endif /* DJGPP */
  327.  
  328. #ifdef VMS
  329.     unsigned int status[2] = { 1, 0 };
  330. #endif
  331.  
  332. #ifdef GNU_READLINE
  333.     rl_readline_name = argv[0];
  334.     rl_complete_with_tilde_expansion = 1;
  335. #endif
  336.  
  337. #ifdef X11
  338.     {
  339.     int n = X11_args(argc, argv);
  340.     argv += n;
  341.     argc -= n;
  342.     }
  343. #endif
  344.  
  345. #ifdef apollo
  346.     apollo_pfm_catch();
  347. #endif
  348.  
  349. /* moved to ATARI_init in atariaes.trm */
  350. /* #ifdef ATARI
  351.    void application_init(void);
  352.    application_init();
  353.    #endif */
  354.  
  355. #ifdef MTOS
  356.     MTOS_open_pipe();
  357. #endif
  358.  
  359.     setbuf(stderr, (char *) NULL);
  360.  
  361. #ifndef NO_SETVBUF
  362.     /* this was once setlinebuf(). Docs say this is
  363.      * identical to setvbuf(,NULL,_IOLBF,0), but MS C
  364.      * faults this (size out of range), so we try with
  365.      * size of 1024 instead. [SAS/C does that, too. -lh]
  366.      * Failing this, I propose we just make the call and
  367.      * ignore the return : its probably not a big deal
  368.      */
  369.     if (setvbuf(stdout, (char *) NULL, _IOLBF, (size_t) 1024) != 0)
  370.     fputs("Could not linebuffer stdout\n", stderr);
  371. #endif
  372.  
  373.     gpoutfile = stdout;
  374.     (void) Gcomplex(&udv_pi.udv_value, Pi, 0.0);
  375.  
  376.     init_memory();
  377.  
  378.     interactive = FALSE;
  379.     init_terminal();        /* can set term type if it likes */
  380.  
  381. #ifdef AMIGA_SC_6_1
  382.     if (IsInteractive(Input()) == DOSTRUE)
  383.     interactive = TRUE;
  384.     else
  385.     interactive = FALSE;
  386. #else
  387. # if (defined(__MSC__) && defined(_Windows)) || defined(__WIN32__)
  388.     interactive = TRUE;
  389. # else
  390.     interactive = isatty(fileno(stdin));
  391. # endif
  392. #endif /* !AMIGA_SC_6_1 */
  393.  
  394.     if (argc > 1)
  395.     interactive = noinputfiles = FALSE;
  396.     else
  397.     noinputfiles = TRUE;
  398.  
  399.     if (interactive)
  400.     show_version(stderr);
  401.  
  402. #ifdef VMS
  403.     /* initialise screen management routines for command recall */
  404.     if (status[1] = smg$create_virtual_keyboard(&vms_vkid) != SS$_NORMAL)
  405.     done(status[1]);
  406.     if (status[1] = smg$create_key_table(&vms_ktid) != SS$_NORMAL)
  407.     done(status[1]);
  408. #endif /* VMS */
  409.  
  410.     if (!setjmp(command_line_env)) {
  411.     /* first time */
  412.     interrupt_setup();
  413.     load_rcfile();
  414.     init_fit();        /* Initialization of fitting module */
  415.  
  416.     if (interactive && term != 0)    /* not unknown */
  417.         fprintf(stderr, "\nTerminal type set to '%s'\n", term->name);
  418.     } else {
  419.     /* come back here from int_error() */
  420. #ifdef AMIGA_SC_6_1
  421.     (void) rawcon(0);
  422. #endif
  423.     load_file_error();    /* if we were in load_file(), cleanup */
  424. #ifdef _Windows
  425.     SetCursor(LoadCursor((HINSTANCE) NULL, IDC_ARROW));
  426. #endif
  427.  
  428. #ifdef VMS
  429.     /* after catching interrupt */
  430.     /* VAX stuffs up stdout on SIGINT while writing to stdout,
  431.        so reopen stdout. */
  432.     if (gpoutfile == stdout) {
  433.         if ((stdout = freopen("SYS$OUTPUT", "w", stdout)) == NULL) {
  434.         /* couldn't reopen it so try opening it instead */
  435.         if ((stdout = fopen("SYS$OUTPUT", "w")) == NULL) {
  436.             /* don't use int_error here - causes infinite loop! */
  437.             fputs("Error opening SYS$OUTPUT as stdout\n", stderr);
  438.         }
  439.         }
  440.         gpoutfile = stdout;
  441.     }
  442. #endif /* VMS */
  443.     if (!interactive && !noinputfiles) {
  444.         term_reset();
  445. #if defined(ATARI) || defined(MTOS)
  446.         if (aesid > -1)
  447.         atexit(appl_exit);
  448. #endif
  449.         return (IO_ERROR);    /* exit on non-interactive error */
  450.     }
  451.     }
  452.  
  453.     if (argc > 1) {
  454. #ifdef _Windows
  455.     int noend = 0;
  456. #endif
  457.  
  458.     /* load filenames given as arguments */
  459.     while (--argc > 0) {
  460.         ++argv;
  461.         c_token = NO_CARET;    /* in case of file not found */
  462. #ifdef _Windows
  463.         if (stricmp(*argv, "-noend") == 0 || stricmp(*argv, "/noend") == 0)
  464.         noend = 1;
  465.         else
  466. #endif
  467.         if (strcmp(*argv, "-") == 0) {
  468.         /* DBT 10-7-98  go interactive if "-" on command line */
  469.  
  470.         interactive = TRUE;
  471.         /* will this work on all platforms? */
  472.  
  473.         while (!com_line());
  474.  
  475.         /* interactive = FALSE; /* should this be here? */
  476.  
  477.         } else
  478.         load_file(fopen(*argv, "r"), *argv, FALSE);
  479.     }
  480. #ifdef _Windows
  481.     if (noend) {
  482.         interactive = TRUE;
  483.         while (!com_line());
  484.     }
  485. #endif
  486.     } else {
  487.     /* take commands from stdin */
  488.     while (!com_line());
  489.     }
  490.  
  491.     term_reset();
  492.  
  493. #ifdef OS2
  494.     if (_osmode == OS2_MODE)
  495.     RexxDeregisterSubcom("GNUPLOT", NULL);
  496. #endif
  497.  
  498. #if defined(ATARI) || defined(MTOS)
  499.     if (aesid > -1)
  500.     atexit(appl_exit);
  501. #endif
  502.     return (IO_SUCCESS);
  503. }
  504.  
  505. #if (defined(ATARI) || defined(MTOS)) && defined(__PUREC__)
  506. int purec_matherr(struct exception *e)
  507. {
  508.     char *c;
  509.     switch (e->type) {
  510.     case DOMAIN:
  511.     c = "domain error";
  512.     break;
  513.     case SING:
  514.     c = "argument singularity";
  515.     break;
  516.     case OVERFLOW:
  517.     c = "overflow range";
  518.     break;
  519.     case UNDERFLOW:
  520.     c = "underflow range";
  521.     break;
  522.     default:
  523.     c = "(unknown error";
  524.     break;
  525.     }
  526.     fprintf(stderr, "\
  527. math exception : %s\n\
  528.     name : %s\n\
  529.     arg 1: %e\n\
  530.     arg 2: %e\n\
  531.     ret  : %e\n",
  532.         c,
  533.         e->name,
  534.         e->arg1,
  535.         e->arg2,
  536.         e->retval);
  537.  
  538.     return 1;
  539. }
  540. #endif /* (ATARI || MTOS) && PUREC */
  541.  
  542.  
  543. /* Set up to catch interrupts */
  544. void interrupt_setup()
  545. {
  546. #ifdef __PUREC__
  547.     setmatherr(purec_matherr);
  548. #endif
  549.  
  550.     (void) signal(SIGINT, (sigfunc) inter);
  551.  
  552. #ifdef SIGPIPE
  553.     /* ignore pipe errors, this might happen with set output "|head" */
  554.     (void) signal(SIGPIPE, SIG_IGN);
  555. #endif /* SIGPIPE */
  556. }
  557.  
  558.  
  559. /* Look for a gnuplot init file in . or home directory */
  560. static void load_rcfile()
  561. {
  562.     FILE *plotrc = NULL;
  563.     char home[80];
  564.     char rcfile[sizeof(PLOTRC) + 80];
  565.     char *tmp_home = NULL;
  566. #ifndef VMS
  567.     char *p;    /* points to last char in home path, or to \0, if none */
  568.  
  569.     tmp_home = getenv(HOME);
  570.     if (tmp_home) {
  571.     safe_strncpy(home, tmp_home, sizeof(home));
  572.     if (strlen(home))
  573.         p = &home[strlen(home) - 1];
  574.     else
  575.         p = home;
  576.     if ((*p != DIRSEP1) && (*p != DIRSEP2) && (*p != NUL)) {
  577.         assert(p >= home && p <= (home + sizeof(home) - 1 - 2));
  578.         if (*p)
  579.         p++;
  580.         *p++ = DIRSEP1;
  581.         *p = NUL;
  582.     }
  583.     }
  584. #else /* VMS */
  585.     safe_strncpy(home, HOME, sizeof(home));
  586.     tmp_home = home;
  587. #endif /* VMS */
  588.  
  589. #ifdef NOCWDRC
  590.     /* inhibit check of init file in current directory for security reasons */
  591. #else
  592.     (void) strcpy(rcfile, PLOTRC);
  593.     plotrc = fopen(rcfile, "r");
  594. #endif /* !NOCWDRC */
  595.  
  596.     if (plotrc == NULL) {
  597.     if (tmp_home) {
  598.         (void) sprintf(rcfile, "%s%s", home, PLOTRC);
  599.         plotrc = fopen(rcfile, "r");
  600. #if defined(ATARI) || defined(MTOS)
  601.         if (plotrc == NULL) {
  602.         char const *const ext[] = { NULL };
  603.         char *ini_ptr = findfile(PLOTRC, getenv("GNUPLOTPATH"), ext);
  604.  
  605.         if (ini_ptr)
  606.             plotrc = fopen(ini_ptr, "r");
  607.         }
  608. #endif /* ATARI || MTOS */
  609.     }
  610.     }
  611.     if (plotrc)
  612.     load_file(plotrc, rcfile, FALSE);
  613. }
  614.  
  615. #ifdef OS2
  616.  
  617. int ExecuteMacro(char *argv, int namelength)
  618. {
  619.     RXSTRING rxRc;
  620.     RXSTRING rxArg;
  621.     char pszName[CCHMAXPATH];
  622.     short sRc;
  623.     int rc;
  624.  
  625.     safe_strncpy(pszName, argv, sizeof(pszName));
  626.     MAKERXSTRING(rxArg, argv, strlen(argv));
  627.     rc = RexxStart(1,
  628.            &rxArg,
  629.            pszName,
  630.            NULL,
  631.            "GNUPLOT",
  632.            RXCOMMAND,
  633.            NULL,
  634.            &sRc,
  635.            &rxRc);
  636.     if (rc == -4)
  637.     rc = 0;            /* run was cancelled-don't give error message */
  638.  
  639. /* We don't use this value ?
  640.    BTW, don't use free() instead since it's allocated inside RexxStart() */
  641.     DosFreeMem(rxRc.strptr);
  642.     return rc;
  643. }
  644.  
  645. ULONG RexxInterface(PRXSTRING rxCmd, PUSHORT pusErr, PRXSTRING rxRc)
  646. /*
  647.    ** Rexx command line interface
  648.  */
  649. {
  650.     int rc;
  651.     static jmp_buf keepenv;
  652.     int cmdlen;
  653.  
  654.     memcpy(keepenv, command_line_env, sizeof(jmp_buf));
  655.     if (!setjmp(command_line_env)) {
  656.     /* set variable input_line.
  657.      * Watch out for line length of NOT_ZERO_TERMINATED strings ! */
  658.     cmdlen = rxCmd->strlength + 1;
  659.     safe_strncpy(input_line, rxCmd->strptr, cmdlen);
  660.     input_line[cmdlen] = NUL;
  661.  
  662.     rc = do_line();
  663.     *pusErr = RXSUBCOM_OK;
  664.     rxRc->strptr[0] = rc + '0';
  665.     rxRc->strptr[1] = NUL;
  666.     rxRc->strlength = strlen(rxRc->strptr);
  667.     } else {
  668.     *pusErr = RXSUBCOM_ERROR;
  669.     RexxSetHalt(getpid(), 1);
  670.     }
  671.     memcpy(command_line_env, keepenv, sizeof(jmp_buf));
  672.     return 0;
  673. }
  674. #endif
  675.